/**
 * 
 */
package com.wy2.generator;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import cn.xo68.core.PropertiesDocument;
import cn.xo68.core.util.FileTools;
import cn.xo68.core.util.StringTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import com.wy2.generator.config.GeneratorConsts;
import com.wy2.generator.exception.GeneratorOutputException;
import com.wy2.generator.resource.Messages;
import com.wy2.generator.util.FreemarkerUtils;
import com.wy2.generator.util.GeneratorUtils;

/**
 * @author nnsword
 * @date 2017-12-21 23:05:10
 *
 */
public class ProjectGenerator {
    private static final Logger logger=LoggerFactory.getLogger(ProjectGenerator.class);
	
	private final PropertiesDocument propertiesDocument;
	
	private final AbstractGenerator baseGenerator;
    private final String templateSuffix;
    
	/**
	 * @return the templateDirectory
	 */
	public File getTemplateDirectory() {
		return baseGenerator.getTemplateDirectory();
	}

	/**
	 * @return the outputRootDirectory
	 */
	public File getOutputRootDirectory() {
		return baseGenerator.getOutputRootDirectory();
	}

	/**
	 * @param baseGenerator
	 * @param templateSuffix
	 */
	public ProjectGenerator(AbstractGenerator baseGenerator, String templateSuffix,PropertiesDocument propertiesDocument) {
		super();
		this.baseGenerator = baseGenerator;
		this.templateSuffix = templateSuffix;
		this.propertiesDocument=propertiesDocument;
	}

	/**
	 * @param propertiesDocument
	 */
	public ProjectGenerator(PropertiesDocument propertiesDocument) {
		super();
		this.propertiesDocument = propertiesDocument;
		String templateDirectory=propertiesDocument.getProperty(GeneratorConsts.GENERATOR_CONFIG_TEMPLATE_DIRECTORY);
		String outputRootDirectory=propertiesDocument.getProperty(GeneratorConsts.GENERATOR_CONFIG_OUTPUT_DIRECTORY);
		String markerTemplateString=propertiesDocument.getProperty(GeneratorConsts.GENERATOR_CONFIG_MARKER_TEMPLATE);
		String encoding=propertiesDocument.getProperty(GeneratorConsts.GENERATOR_CONFIG_ENCODING);
		String suffix=propertiesDocument.getProperty(GeneratorConsts.GENERATOR_CONFIG_TEMPLATE_SUFFIX,GeneratorConsts.GENERATOR_CONFIG_TEMPLATE_SUFFIX_DEFAULT);
		this.templateSuffix =suffix;
		DefaultGenerator generator=new DefaultGenerator(new File(templateDirectory),new File(outputRootDirectory),markerTemplateString,encoding);
		this.baseGenerator=generator;
	}
	
	public LinkedList<GenerateResult> generate(Map<String,Object> model,Boolean override) {
    	final List<File> templates=new ArrayList<File>();
    	searchTemplate(templates);
    	if(templates.size()<1) {
    		throw new GeneratorOutputException(Messages.getString("GeneratorOutputException.4"));
    	}
    	
    	Map<String,Object> context=propertiesDocument.getMap(GeneratorConsts.GENERATOR_CONFIG_TEMPLATE_ATTRIBUTE_PREFIX, true);
    	if(context==null) {
    		context=new HashMap<String, Object>();
    	}
		if(model!=null) {
			context.putAll(model);
		}
    	
        //把基础包路径转化为文件路径 
        if(context.containsKey(GeneratorConsts.TEMPLATE_ATTRI_BASEPACKAGE)) {
            String basePackagePath=context.get(GeneratorConsts.TEMPLATE_ATTRI_BASEPACKAGE).toString().replace(".", "/");
            context.put(GeneratorConsts.TEMPLATE_ATTRI_BASEPACKAGE_PATH, basePackagePath);
        }
        
        //输出路径模板计算
        List<String> outputPathTemplates=new ArrayList<String>();
        String outputPathTemplate;        
        for (File template : templates) {
        	outputPathTemplate=GeneratorUtils.getOutputPathTemplateByTemplateFile(baseGenerator, template, templateSuffix);
        	outputPathTemplates.add(FreemarkerUtils.stringTemplateEncode(outputPathTemplate));
		}
        baseGenerator.initTemplateConfig(outputPathTemplates.toArray(new String[0]));
        
      //是否需要通过模板引擎与数据合并
        Boolean marge=false;
        //输出相对路径
        String relativeOutputPath;
        LinkedList<GenerateResult> generateResults=new LinkedList<GenerateResult>();
        GenerateResult generateResult;
        for (File template : templates) {
        	if(template.getAbsolutePath().toLowerCase().endsWith(templateSuffix.toLowerCase())) {
        		marge=true;
        	}else {
        		marge=false;
        	}
        	if(marge) {
        		outputPathTemplate=GeneratorUtils.getOutputPathTemplateByTemplateFile(baseGenerator, template, templateSuffix);
        		relativeOutputPath=baseGenerator.output(FreemarkerUtils.stringTemplateEncode(outputPathTemplate), context, baseGenerator.getTemplateEncoding());
            	generateResult=baseGenerator.outputFile(outputPathTemplate+this.templateSuffix, context, relativeOutputPath, override, baseGenerator.getTemplateEncoding());
            	generateResults.add(generateResult);
        	}else {
        		//不合并的，直接复制
        		outputPathTemplate=GeneratorUtils.getOutputPathTemplateByTemplateFile(baseGenerator, template, templateSuffix);
        		relativeOutputPath=baseGenerator.output(FreemarkerUtils.stringTemplateEncode(outputPathTemplate), context, baseGenerator.getTemplateEncoding());
        		FileTools.copyFile(new File(this.getTemplateDirectory(), outputPathTemplate), new File(this.getOutputRootDirectory(), relativeOutputPath));
        		generateResult=new GenerateResult(baseGenerator.getMarkerString(context), relativeOutputPath, true, false);
            	generateResults.add(generateResult);
        	}
		}
        return generateResults;
    }
	
	
    
    private void searchTemplate(final List<File> templates) {
    	FileTools.searchFile(templates, baseGenerator.getTemplateDirectory(), StringTools.EMPTY);
    }
	
}
